package com.rambo.hcq.server;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import java.util.List;

/**
 * 通用数据查询实现类
 *
 * @author Rambo 2017/12/2
 */
@Component
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class CommonQueryWsImpl implements CommonQueryWs {

    @Resource
    private SessionFactory sessionFactory;

    @Override
    @Transactional(readOnly = true)
    public String getPo(String poName, List<String> andList) {
        DetachedCriteria detachedCriteria = getDetachedCriteria(poName, andList);

        Object result = detachedCriteria.getExecutableCriteria(sessionFactory.getCurrentSession()).setMaxResults(1).uniqueResult();
        return ObjectUtil.isNull(result) ? "{}" : JSONUtil.toJsonStr(result);
    }

    @Override
    @Transactional(readOnly = true)
    public String listPo(String poName, List<String> andList) {
        DetachedCriteria detachedCriteria = getDetachedCriteria(poName, andList);

        List list = detachedCriteria.getExecutableCriteria(sessionFactory.getCurrentSession()).list();
        return JSONUtil.toJsonStr(list);
    }

    /**
     * 获取 hiber 离线查询对象
     *
     * @param poName  biber 实体对象
     * @param andList andSql 列表
     * @return 离线查询对象
     */
    private DetachedCriteria getDetachedCriteria(String poName, List<String> andList) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forEntityName(poName);

        String[] split;
        for (String andStr : andList) {
            split = Base64.decodeStr(andStr).split("#");
            String andSql = split[0];
            String andParam = split[1];

            if (andParam.contains(",")) {
                String[] andParams = andParam.split(",");
                Type[] types = new Type[andParams.length];
                for (int i = 0; i < types.length; i++) {
                    types[i] = StringType.INSTANCE;
                }

                detachedCriteria.add(Restrictions.sqlRestriction(andSql, andParams, types));
            } else {
                detachedCriteria.add(Restrictions.sqlRestriction(andSql, andParam, StringType.INSTANCE));
            }
        }
        return detachedCriteria;
    }
}